/**
 * @desc 组件管理
 * @author: FFFF
 */
import { ref, reactive, toRaw, getCurrentInstance, defineAsyncComponent } from 'vue'
import { filterItem, cloneObject } from './common/util/util.js'

// 组件列表
export const componentList = reactive([]);
// 组件分组数据
export const componentGroup = reactive([]);
// 组件实例
export const componentInstance = reactive([]);


// 是否初始化
let initialized = reactive(false)

/**
 * 初始化组件
 * 该函数负责初始化相关的组件
 * @param {无} 该函数不接受任何参数。
 * @return {无} 该函数没有返回值。
 */
export function initComponents() {

    if (!initialized) {
        initialized = true;

        const { proxy } = getCurrentInstance()
        // 加载注册的组件
        const registerComponentData = proxy.$registerComponentsData;

        if (registerComponentData != undefined) {
            registerComponent(registerComponentData);
        }
    }

}

/**
 * @method
 * @param {Object,Array} data 组件数据,可为对象或者数组
 * @desc 注册组件
 */
export function registerComponent(data) {

    if (Array.isArray(data)) {
        // 如果是数组
        for (let i = 0; i < data.length; i++) {
            let item = data[i];
            loadRegComponent(item);
        }
    } else {
        // 如果是对象
        loadRegComponent(data);
    }

    setComponentGroupId();
    setComponentGroup();
}

/**
 * @method
 * @param {Object} obj 组件对象
 * @desc 加载注册的组件
 */
const loadRegComponent = (obj) => {

    // 如果分组未设置isShow属性，则设置默认值
    if (obj.isShow == undefined) obj.isShow = true;

    // 循环分组内的组件list
    for (let i = 0; i < obj.list.length; i++) {
        let item = obj.list[i];
        // 如果组件未设置componentProps属性，则设置默认值
        if (!item.componentProps) {
            item.componentProps = { bordered: true, style: {} }
        } else if (!item.componentProps.style) {
            item.componentProps.style = {};
        }

        // 如果组件未设置isShow属性，则设置默认值
        if (item.isShow == undefined) item.isShow = true;
        setComponentInstance(item);
    }

    componentList.push(obj);
}

/**
 * 设置组件分组的ID
 */
const setComponentGroupId = () => {
    for (let i = 0; i < componentList.length; i++) {
        let groupItem = componentList[i];
        groupItem.id = i + 1;
    }
}


/**
 * 设置分组数据，以便搜索功能使用
 */
const setComponentGroup = () => {
    for (let i = 0; i < componentList.length; i++) {
        let groupItem = componentList[i];
        componentGroup.push({
            id: groupItem.id,
            groupName: groupItem.groupName,
            isShow: groupItem.isShow,
            list: []
        })
    }
}

/**
 * @method
 * @param {Object} obj 组件对象
 * @desc 设置组件实例
 */
const setComponentInstance = (obj) => {
    componentInstance.push({
        component: obj.component,
        componentOptions: obj.componentOptions,
        event: obj.event,
        name: obj.name,
        label: obj.label,
        type: obj.type
    })

    delete obj.event;
    delete obj.component;
    delete obj.componentOptions;

    if (obj.children && obj.children.length > 0) {
        for (let i = 0; i < obj.children.length; i++) {
            let item = obj.children[i];
            setComponentInstance(item);
        }
    }
}

/**
 * @method
 * @param {String} type 组件的type
 * @desc 获取组件实例
 */
export const getComponentInstance = (type) => {
    let eventObj;
    for (let i = 0; i < componentInstance.length; i++) {
        let item = componentInstance[i];
        if (item.type == type) {
            eventObj = item;
        }
    }
    return eventObj;
}


/**
 * @method
 * @desc 获取全部组件实例
 */
export const getAllComponentInstance = () => {
    return componentInstance;
}


/**
 * @method
 * @param {String} groupName 分组名称
 * @desc 获取组件分组对象
 */
const getGroupObj = (groupName) => {
    let groupObj;
    for (let i = 0; i < componentList.length; i++) {
        let groupItem = componentList[i];
        if (groupItem.groupName == groupName) {
            groupObj = groupItem;
        }
    }
    return groupObj;
}


/**
 * @method
 * @param {Object} component 组件
 * @desc 异步加载组件
 */
export const loadAsyncComponent = (component) => {
    return defineAsyncComponent(component);
}


/**
 * @method
 * @param {String} name 组件名称
 * @desc 搜索组件
 */
export const searchComponent = (name) => {

    // 复制组数据
    let groupData = cloneObject(componentGroup);
    groupData = groupData.filter((obj, index) => groupData.findIndex((item) => item.id === obj.id) === index);

    let searchData = [];

    // 查询组件
    for (let i = 0; i < componentList.length; i++) {
        let item = componentList[i];
        for (let j = 0; j < item.list.length; j++) {
            const item1 = item.list[j];
            if (item1.name.indexOf(name) != -1) {
                searchData.push(item1);
            }
        }
    }

    if (searchData.length > 0) {
        // 赋值到组数据中
        for (let j = 0; j < groupData.length; j++) {
            let groupItem = groupData[j];
            for (let x = 0; x < searchData.length; x++) {
                let searchItem = searchData[x];
                if (groupItem.groupName == searchItem.groupName) {
                    groupItem.list.push(searchItem);
                }
            }
        }

        // 清除组数据中的空组
        let searchResult = groupData.filter((groupItem) => {
            return groupItem.list.length > 0;
        });

        return searchResult;
    } else {
        return [];
    }
}


/**
 * @method
 * @param {String} type 布局类型
 * @desc 设置组件的布局类型
 */

export const setComponentLayout = (type) => {
    for (let i = 0; i < componentList.length; i++) {
        let groupItem = componentList[i];
        for (let j = 0; j < groupItem.list.length; j++) {
            let item = groupItem.list[j];
            item.layoutType = type;
        }
    }
}

/**
 * 获取当前已注册的组件数据
 * @returns 返回组件列表数据
 */
export const getCompList = () => {
    return componentList;
}

/**
 * 获取组件
 * @param {String} name 组件name 
 */
export const getComp = (name) => {
    let returnData = [];
    for (let i = 0; i < componentList.length; i++) {
        const groupItem = componentList[i];
        for (let j = 0; j < groupItem.list.length; j++) {
            const item = groupItem.list[j];
            if (item.name === name) {
                // return item;
                returnData.push(item);
            }
        }
    }

    if (returnData.length > 1) {
        // 如果查询到多个组件，则返回数组
        return returnData;
    } else if (returnData.length == 1) {
        // 如果查询到单个组件，则返回对象
        return returnData[0];
    } else {
        // 如果查询不到组件，则返回null
        return null;
    }
}

/**
 * 隐藏对应组件
 * @param {String} name 组件名称
 * @returns 返回操作的组件
 */
export const hideComp = (name) => {
    let item = getComp(name);
    if (Array.isArray(item)) {
        for (let i = 0; i < item.length; i++) {
            item[i].isShow = false;
        }
    } else if (item != null) {
        item.isShow = false;
    }
    return item;
}

/**
 * 显示对应组件
 * @param {String} name 组件名称
 * @returns 返回操作的组件
 */
export const showComp = (name) => {
    let item = getComp(name);
    if (Array.isArray(item)) {
        for (let i = 0; i < item.length; i++) {
            item[i].isShow = true;
        }
    } else if (item != null) {
        item.isShow = true;
    }
    return item;
}

/**
 * 获取分组
 * @param {String} name 分组name 
 */
export const getCompGroup = (name) => {
    let returnData = [];
    for (let i = 0; i < componentList.length; i++) {
        const groupItem = componentList[i];
        if (groupItem.groupName === name) {
            returnData.push(groupItem);
        }
    }
    if (returnData.length > 1) {
        // 如果查询到多个组件，则返回数组
        return returnData;
    } else if (returnData.length == 1) {
        // 如果查询到单个组件，则返回对象
        return returnData[0];
    } else {
        // 如果查询不到组件，则返回null
        return null;
    }

}


/**
 * 隐藏对应分组
 * @param {String} name 分组名称
 * @returns 返回操作的分组
 */
export const hideCompGroup = (name) => {
    let item = getCompGroup(name);

    console.log("获取的分组：",item)

    if (Array.isArray(item)) {
        for (let i = 0; i < item.length; i++) {
            item[i].isShow = false;
        }
    } else if (item != null) {
        item.isShow = false;
    }
    return item;
}

/**
 * 显示对应分组
 * @param {String} name 分组名称
 * @returns 返回操作的分组
 */
export const showCompGroup = (name) => {
    let item = getCompGroup(name);
    if (Array.isArray(item)) {
        for (let i = 0; i < item.length; i++) {
            item[i].isShow = true;
        }
    } else if (item != null) {
        item.isShow = true;
    }
    return item;
}